from django import template
from django import forms
from django.http import HttpResponseRedirect
from pirate_forum.templatetags.blobtags import get_form
from pirate_forum.models import ForumDimension
from pirate_consensus.models import Consensus

from pirate_topics.models import Topic
from pirate_core.views import HttpRedirectException, namespace_get

from customtags.decorators import block_decorator
register = template.Library()
block = block_decorator(register)

get_namespace = namespace_get('pp_topic')


@block
def pp_get_topic(context, nodelist, *args, **kwargs):

    context.push()
    namespace = get_namespace(context)

    obj = kwargs.pop('object', None)
    topicname = kwargs.pop('topicname', None)
    if topicname is not None:
        try:
            topic = Topic.objects.get(summary=topicname)
        except:
            topic = None
    else:
        topic = None
    parent = None
    if obj is not None:
        try:
            if obj.get_child_blob_key():
                parent = obj
        except:
            try:
                if obj.parent.summary != '__NULL__':
                    parent = obj.parent
                else:
                    parent = obj
            except:
                pass

    namespace['parent'] = parent
    namespace['topic'] = topic


    output = nodelist.render(context)
    context.pop()

    return output



@block
def pp_get_topic_hierarchy(context, nodelist, *args, **kwargs):
    """
    This block tag will grab the parent of a topic. Each Topic object contains
    a parent or if a root node contains a null value. In this case the object returned
    is either that parent, or the None object.

    {% pp_get_topic_hierarchy topic = object %}
       Do stuff with {{ pp_topic.hierarchy }}
    {% endpp_get_topic_hierarchy %}
    """

    context.push()
    namespace = get_namespace(context)

    root = kwargs.pop('topic',None)

    if root != None and isinstance(root,Topic):

        hierarchy = []
        hierarchy.insert(0,root)

        parent = root.parent

        while parent != None and parent.summary != '__NULL__':
            parent = root.parent
            hierarchy.insert(0,parent)
    else:
        hierarchy = None

    namespace['hierarchy'] = hierarchy
    output = nodelist.render(context)
    context.pop()

    return output

@block
def pp_get_topic_list(context, nodelist, *args, **kwargs):
    """
    This block tag will grab a list of topics. This also takes an argument 'topic'
    allowing the template to specify a root topic, in which case each child of this topic 
    will be included in 'children'.

    In order to generate a url that will provide rng information to this tag via
    request.range, use a url tag of the following form:

    {% url pp-page template="filename.html" start=0 end=20 %}

    In this way, the tag can be invoked as follows:

    {% pp_get_topic_list range=request.range topic = root_topic %}
       Do stuff with {{ pp_topic.topic_list }}
    {% endpp_get_topic_list %}

    >>> from pirate_issues.models import Topic
    >>> topic = Topic(text = "newtopic")
    >>> topic.save()
    >>> topic2 = Topic(text = "childtopic", parent = topic)
    >>> topic2.save()
    >>> topic3 = Topic(text = "nexttopic", parent = topic2)
    >>> Topic.objects.all()
    [<Topic: taxes>, <Topic: debt>, <Topic: A test topic.>, <Topic: newtopic>, <Topic: childtopic>]
    >>> Topic.clean_objects.filter(parent = topic)
    [<Topic: childtopic>]
    >>> Topic.clean_objects.filter(parent = Topic.objects.null_dimension())
    []
    """

    context.push()
    namespace = get_namespace(context)
    rng = kwargs.pop('range',None)
    root = kwargs.pop('topic',None)
    final_topic_list = []

    if isinstance(rng, basestring):
        try:
            rng = rng.strip("()").split(",")
            rng = (int(rng[0]), int(rng[1]))
        except:
            rng = None
            
    if rng != None and len(rng) != 2:
        raise ValueError("The argument 'range='"+ str(rng) + "  to the pp_topic_list tag "
                         "must be provided either in the form of an (int, int) pair, or "
                         "as a string in the form of '(<int>, <int>)'.")
    if root != None and isinstance(root, Topic):
        topic_list = Topic.clean_objects.filter(parent = root)
    else:
        topic_list = Topic.clean_objects.filter(parent = Topic.objects.null_dimension())
    if rng:
        topic_list = topic_list[rng[0]:rng[1]]
        
    keys = ForumDimension.objects.values('key')
    
    for topic in topic_list: 
        topic_model_list = []
        for key_dict in keys:
            key = key_dict['key']
            if key not in ['r', 's', 'y', 'n']: #subsumed by yea and nay
                m_form, mod, str_mod = get_form(key)
                mod_l = mod.objects.filter(parent_pk=topic.pk)
                topic_model_list.append((str_mod, len(mod_l)))   
        final_topic_list.append((topic, topic_model_list))


    namespace['topic_list'] = final_topic_list
    #namespace['topic_list'] = topic_list
    output = nodelist.render(context)
    context.pop()

    return output
    
@block
def pp_topic_form(context, nodelist, *args, **kwargs):
    '''
    This block tag can create or process forms eitfrom genericview.views import HttpRedirectException, namespace_gether to create or to modify arguments.
    Usage is as follows:

    {% pp_topic_form POST=request.POST path=request.path topic=pp_topic.topic root=some_topic %}
       Do stuff with {{ pp_topic.form }}.
    {% endpp_topic_form %}
    '''
    context.push()
    namespace = get_namespace(context)

    POST  = kwargs.get('POST', None)
    path  = kwargs.get('path', "")
    topic = kwargs.get('topic',None)
    root = kwargs.get('root', Topic.objects.null_dimension())
    

    if POST and POST.get("form_id") == "pp_topic_form":
        form = TopicForm(POST) if topic is None else TopicForm(POST, instance=topic)
        if form.is_valid():
            new_topic = form.save(commit = False)
            if root and isinstance(root,Topic):
                new_topic.parent = root
                new_topic.save()
            else:
                new_topic.parent = Topic.objects.null_dimension()
                new_topic.save()
            raise HttpRedirectException(HttpResponseRedirect("/topics.html"))
    else:
        form = TopicForm() if topic is None else TopicForm(instance=topic)

    namespace['form'] = form
    output = nodelist.render(context)
    context.pop()

    return output    
    
class TopicForm(forms.ModelForm):
    class Meta:
        model = Topic
        
    form_id = forms.CharField(widget=forms.HiddenInput(), initial="pp_topic_form")
